package L1;

import java.util.concurrent.locks.LockSupport;
import java.util.logging.Logger;

import static java.lang.Thread.sleep;


public class MonitorDemo {
    final static Object obj = new Object();
    static Logger log;
    //sleep 是 Thread 方法，而 wait 是 Object 的方法
    // 2) sleep 不需要强制和 synchronized 配合使用，但 wait 需要和 synchronized 一起用
    // 3) sleep 在睡眠的同时，不会释放对象锁的，但 wait 在等待的时候会释放对象锁
    // 4) 它们状态 TIMED_WAITING

    public static void main(String[] args) throws InterruptedException {
        new Thread(() -> {
            synchronized (obj) {
                System.out.println("执行....");
                try {
                    obj.wait(); // 让线程在obj上一直等待下去
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("其它代码....");
            }
        }).start();
        new Thread(() -> {
            synchronized (obj) {
                System.out.println("执行....");
                try {
                    obj.wait(); // 让线程在obj上一直等待下去
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("其它代码....");
            }
        }).start();
        // 主线程两秒后执行
        sleep(2);
        System.out.println("唤醒 obj 上其它线程");
        synchronized (obj) {
            obj.notify(); // 唤醒obj上一个线程
            // obj.notifyAll(); // 唤醒obj上所有等待线程
        }


        Thread t1 = new Thread(() -> {
            System.out.println();
            System.out.println("start...");
            try {
                sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println();
            LockSupport.park();
            System.out.println("park...");
            LockSupport.park("resume...");
        }, "t1");
        t1.start();
        sleep(2);
        System.out.println("unpark...");
        LockSupport.unpark(t1);

    }

}
